package com.zsc.wxapp.services.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zsc.wxapp.clients.RemotePriceInfoClient;
import com.zsc.wxapp.constant.EndUserTime;
import com.zsc.wxapp.context.BaseContext;
import com.zsc.wxapp.entity.*;
import com.zsc.wxapp.entity.dto.PriceTagDTO;
import com.zsc.wxapp.entity.dto.SubmitTaskDTO;
import com.zsc.wxapp.entity.external.PriceNameData;
import com.zsc.wxapp.entity.external.ProductDetails;
import com.zsc.wxapp.entity.external.PriceOverview;
import com.zsc.wxapp.entity.vo.*;
import com.zsc.wxapp.exservices.Remote2;
import com.zsc.wxapp.mapper.*;
import com.zsc.wxapp.services.PriceTagService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class PriceTagServiceImpl implements PriceTagService {

    @Resource
    private PriceTagMapper priceTagMapper;
    @Resource
    private RemotePriceInfoClient remotePriceInfoClient;
    @Resource
    private UserMapper userMapper;
    @Resource
    private Remote2 remote2;
    @Resource
    private PrintTaskMapper printTaskMapper;
    @Resource
    private CustomerOfManagerMapper customerOfManagerMapper;
    @Resource
    private CodeOfCustMapper codeOfCustMapper;

    public List<IPriceTag> findAll() {
        return priceTagMapper.findAll();
    }

    public int insert(IPriceTag priceTag) {

        return priceTagMapper.insert(priceTag);
//        return 0;
    }

    public int deleteById(String id) {
        return priceTagMapper.deleteByPrimaryKey(id);
    }

    public int update(IPriceTag priceTag) {
        return priceTagMapper.updateByPrimaryKeySelective(priceTag);
//        return 0;
    }


    @Override
    public List<PriceOverview> updateProductUserRetailPrice(List<PriceOverview> productList) {
        for (PriceOverview product : productList) {
            // 根据product_name查询user_retail_price
            Double userRetailPrice = priceTagMapper.findUserRetailPriceByProductName(product.getProductName());
            // 如果查询到值，则更新Product对象
            if (userRetailPrice != null) {
                System.out.println(userRetailPrice);
                product.setRecognizedPrice(userRetailPrice);
            }
        }
        return productList;
    }

    @Override
    public List<PriceOverview> getPriceOverview() {
        List<PriceOverview> priceOverviewList = remotePriceInfoClient.getPriceOverview();
//        List<priceOverview> priceOverviewList=remote2.getPriceOverview();
        priceOverviewList = updateProductUserRetailPrice(priceOverviewList);
        return priceOverviewList;
    }

    @Override
    public List<PriceNameData> getPriceData(String productUuid) {
        return priceTagMapper.getPriceData(productUuid);
    }

    @Override
    public List<ProductDetails> getProductDetails(String productUuid) {
        return priceTagMapper.getProductDetails(productUuid);
    }

    /**
     * 根据产品名称查找产品信息
     *
     * @param name
     * @param products
     * @return ProductVO
     */
    private ProductVO findProductByName(String name, List<ProductVO> products) {
        log.warn("根据产品名称查找产品信息：name:{}", name);
        log.warn("产品列表：{}", products);
        return products.stream().filter(product -> product.getProductName().equals(name)).findFirst().orElse(null);
    }

    /**
     * 添加价签数据
     *
     * @param priceTagDTOs
     * @param userId
     */
    @Override
    public void addPriceTags(List<PriceTagDTO> priceTagDTOs, Long userId) {
        log.warn("添加价签数据，priceTagDTOs:{}", priceTagDTOs);
        List<PriceTag> list = new ArrayList<>();

        for (PriceTagDTO priceTagDTO : priceTagDTOs) {
            CigaretteVO cigaretteVO = remote2.getByCode(priceTagDTO.getProductCode());

            //判断价格情况
            log.info("指导价格是：{}", cigaretteVO.getDirectRetailPrice());
            BigDecimal difference = cigaretteVO.getDirectRetailPrice().subtract(priceTagDTO.getUpdatePrice());
            String status = "2";
            if (difference.compareTo(BigDecimal.ZERO) == 1 && difference.compareTo(new BigDecimal("10")) == 1) {
                status = "0";
            } else if (difference.compareTo(BigDecimal.ZERO) == -1 && difference.abs().compareTo(new BigDecimal("10")) == 1) {
                status = "1";
            }

            BigDecimal directRetailPrice = cigaretteVO.getDirectRetailPrice().divide((cigaretteVO.getPackageQty2().divide(cigaretteVO.getPackageQty(), 2, RoundingMode.HALF_UP)), 2, RoundingMode.HALF_UP);

            PriceTag priceTag = PriceTag.builder()
                    .userId(userId)
                    .custUuid(userMapper.selectUserById(userId).getCustomUuid())
                    .productName(cigaretteVO.getProductName())
                    .productCode(priceTagDTO.getProductCode())
                    .recognizedPrice(priceTagDTO.getUpdatePrice())
                    .packageQty(cigaretteVO.getPackageQty())
                    .directRetailPrice(directRetailPrice)
                    .tagStatus(status)
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
            list.add(priceTag);
        }

        // 判断数据库中是否有数据
        List<PriceTag> originalPriceTags = priceTagMapper.getAllByUserId(userId);

        for (PriceTag priceTag : list) {
            PriceTag selectResult = getTagByCode(originalPriceTags, priceTag.getProductCode());
            if (selectResult != null) {
                // 该价签原本就存在数据库中，做更新操作
                PriceTagDTO priceTagDTO = PriceTagDTO.builder()
                        .priceTagId(selectResult.getPriceTagId())
                        .updatePrice(priceTag.getRecognizedPrice())
                        .updateTime(LocalDateTime.now())
                        .build();
                log.warn("更新数据, priceTag:{}", priceTag);
                log.warn("更新数据，selectResult:{}", selectResult);
                priceTagMapper.updatePriceTagById(priceTagDTO);
            } else {
                //数据库中没有数据，做添加操作
                priceTagMapper.insertPriceTag(priceTag);
            }
        }

        //找到用户，给用户添加拍照次数
        Integer photoTimes = userMapper.selectUserById(userId).getPhotoTimes() + 1;
        Integer addVipDays = userMapper.selectUserById(userId).getVipRewardDays() + 7;
        //更新数据库表中的数据
        userMapper.updateUserPhotoTimes(photoTimes, addVipDays, Math.toIntExact(userId), LocalDate.now());
    }

    /**
     * 根据卷烟代码code来查找list中是否也有对应数据
     *
     * @param originalPriceTags 数据库中原有的数据
     * @param productCode       卷烟代码
     * @return PriceTag 价签对象
     */
    private PriceTag getTagByCode(List<PriceTag> originalPriceTags, String productCode) {
        return originalPriceTags.stream()
                .filter(entity -> entity.getProductCode().equals(productCode))
                .findFirst()
                .orElse(null);
    }

    /**
     * 根据用户id获取价签数据
     *
     * @return List
     */
    @Override
    public List<PriceTagVO> getPriceTagsByUserId(Long userId) {
        //获取到当前用户最近上传的日期

        List<PriceTag> list = priceTagMapper.getNewPriceTagsByUserId(userId);
        if (list.isEmpty()) {
            log.warn("当前用户没有上传过价签数据");
            return null;
        }
        List<PriceTagVO> result = new ArrayList<>();
        for (PriceTag priceTag : list) {
            PriceTagVO priceTagVO = new PriceTagVO();
            BeanUtils.copyProperties(priceTag, priceTagVO);
            result.add(priceTagVO);
        }
        return result;
    }

    /**
     * 终端用户盈利分析终端用户盈利分析
     *
     * @param userId 用户id
     * @return ProfitAnalysisVO
     */
    @Override
    public ProfitAnalysisVO profitAnalysis(Long userId) {
        //获取用户已经上传的价签数据
        List<PriceTag> priceTagList = priceTagMapper.getPriceTagByUserId(userId);
        if (priceTagList == null) {
            return null;
        }

        //获取用户最近一次的订单数据
        List<OrderVO> orderList = remote2.getLastOrderListByCustUuid(userMapper.selectUserById(userId).getCustomUuid());
        log.info("订单数据：{}", orderList);

        BigDecimal orderAmount = BigDecimal.ZERO;
        BigDecimal preProfit = BigDecimal.ZERO;
        BigDecimal orderNum = BigDecimal.ZERO;

        List<DetailProfitAnalysisVO> detailProfitAnalysisVOList = new ArrayList<>();

        //遍历订单数据，判断是否有订单数据
        for (PriceTag priceTag : priceTagList) {
            for (OrderVO orderVO : orderList) {
                if (priceTag.getProductCode().equals(orderVO.getProductCode())) {
                    //最近一次订单中有数据
                    orderAmount = orderAmount.add(orderVO.getWithTaxAmt());
                    DetailProfitAnalysisVO detailProfitAnalysisVO = DetailProfitAnalysisVO.builder()
                            .productName(priceTag.getProductName())
                            .orderNum(orderVO.getQty())
                            .profit(orderVO.getWithTaxAmt().subtract(priceTag.getRecognizedPrice().multiply(orderVO.getQty())))
                            .productCode(priceTag.getProductCode())
                            .build();
                    detailProfitAnalysisVOList.add(detailProfitAnalysisVO);
                }
            }
        }

        //统计处理后的数据
        for (DetailProfitAnalysisVO d : detailProfitAnalysisVOList) {
            preProfit = preProfit.add(d.getProfit());
            orderNum = orderNum.add(d.getOrderNum());
        }

        ProfitAnalysisVO profitAnalysisVO = ProfitAnalysisVO.builder()
                .detailProfitAnalysisVOList(detailProfitAnalysisVOList)
                .orderAmount(orderAmount)
                .orderNum(orderNum)
                .preProfit(preProfit)
                .build();

        return profitAnalysisVO;
    }

    /**
     * 根据价签id修改价签数据 弃用
     *
     * @param priceTagDTO
     */
    @Override
    public void updatePriceTag(PriceTagDTO priceTagDTO) {
        priceTagMapper.updatePriceTagById(priceTagDTO);
    }

    /**
     * C端用户提交任务到B端用户
     *
     * @param submitTaskDTO
     */
    @Override
    public void submitTask(SubmitTaskDTO submitTaskDTO) {
        PrintTask task = new PrintTask();
        BeanUtils.copyProperties(submitTaskDTO, task);

        String ids = "[" + submitTaskDTO.getPriceTagIds().stream()
                .map(String::valueOf)
                .collect(Collectors.joining(",")) + "]";

        // 获得上传任务用户对应的客户专员
        task.setPriceTagIds(ids);
        task.setCreateTime(LocalDateTime.now());
        task.setReceiveUserId(13L);
        printTaskMapper.insertTask(task);

        // 更新零售用户的个人数据
        userMapper.updateTimes(EndUserTime.SUBMIT_TIME, task.getSubmitUserId());
    }

    /**
     * 根据卷烟名称搜索价签信息
     *
     * @param name 卷烟名称
     * @return List
     */
    @Override
    public List<PriceTagVO> searchPriceTagByName(Long userId, String name) {
        List<PriceTag> list = priceTagMapper.searchPriceTagByName(userId, name);
        List<PriceTagVO> result = new ArrayList<>();
        if (list.isEmpty()) {
            return null;
        }
        for (PriceTag priceTag : list) {
            PriceTagVO priceTagVO = new PriceTagVO();
            BeanUtils.copyProperties(priceTag, priceTagVO);
            result.add(priceTagVO);
        }
        return result;
    }

    /**
     * 批量删除价签
     *
     * @param priceTagDTOs 价签ids
     */
    @Override
    public void deleteByIds(List<PriceTagDTO> priceTagDTOs) {
        for (PriceTagDTO priceTagDTO : priceTagDTOs) {
            priceTagMapper.deleteById(priceTagDTO.getPriceTagId());
        }
    }

    /**
     * 根据id获取价签信息
     *
     * @param id
     * @return
     */
    @Override
    public PriceTagVO getPriceTagById(Long id) {
        PriceTag priceTag = priceTagMapper.getPriceTagById(id);
        if (priceTag != null) {
            PriceTagVO priceTagVO = new PriceTagVO();
            BeanUtils.copyProperties(priceTag, priceTagVO);
            return priceTagVO;
        }
        return null;
    }

    /**
     * 获取B端客户经理管理的所有零售用户
     *
     * @return List
     */
    @Override
    public List<CustomerVO> getCustomers() {
        List<CustomerVO> result = new ArrayList<>();

        // 获取user表中的数据
        Long userId = BaseContext.getCurrentId();
        List<User> userList = userMapper.getAllEndUser(userId);

        // 遍历userList，获取到用户id，通过id获取到客户信息
        for (User user : userList) {
            CustomerVO customerVO = remote2.getCustomerInfoByCustUuid(user.getCustomUuid());
            result.add(customerVO);
        }

        return result;
    }

    /**
     * 分页查询用户
     * @return
     */
    @Override
    public PageInfo pageGetCustomers(Integer pageNum) {
        //获取到客户经理的名称
        Long userId = BaseContext.getCurrentId();
        String username = userMapper.selectUserById(userId).getName();

        //开始分页
        PageHelper.startPage(pageNum, 15);
        List<CustomerOfManager> pageList = customerOfManagerMapper.getCustomerByManager(username);
        PageInfo result = new PageInfo<>(pageList);
        List<CustomerVO> page = new ArrayList<>();

        // 遍历list中的数据，获取到零售用户的uuid，再远程查询用户数据
        for (CustomerOfManager customerOfManager : pageList) {
            String code = customerOfManager.getCustCode();
            String uuid = codeOfCustMapper.selectUuidByCode(code);
            CustomerVO c = remote2.getCustomerInfoByCustUuid(uuid);
            page.add(c);
        }

        // 获取本系统的用户数据
        List<User> userList = userMapper.getAllEndUser(userId);

        // 创建一个 Set 存储 userList 中的 UUID
        Set<String> userUuids = userList.stream()
                .map(User::getCustomUuid)
                .collect(Collectors.toSet());

        // 遍历 customerVO 列表，设置 isRegister
        page.forEach(customerVO ->
                customerVO.setIsRegister(userUuids.contains(customerVO.getCustUuid()) ? 1 : 0)
        );


        result.setList(page);

        // 验证数据
        for (CustomerVO customerVO : page) {
            if (customerVO.getIsRegister() == 1) {
                log.info("已经注册的用户为：{}", customerVO);
            }
        }

        return result;
    }
}